package com.media.photocamera.activity

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Build
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Log
import android.util.Rational
import android.util.Size
import android.view.View
import android.view.View.OnTouchListener
import android.view.WindowManager
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.camera.core.*
import androidx.camera.core.impl.utils.executor.CameraXExecutors
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.media.photocamera.imagelist.CameraImageBean
import top.zibin.luban.Luban
import java.io.File
import java.util.*
import com.media.photocamera.R
import com.media.photocamera.imagelist.PreviewImageAdapter
import com.media.photocamera.utils.CameraConstans
import com.media.photocamera.utils.CameraFileUtils
import java.util.concurrent.ExecutionException

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@SuppressLint("RestrictedApi")
class CameraXActivity : com.media.photocamera.activity.BaseCameraXActivity(), View.OnClickListener, PreviewImageAdapter.ChangeCallBack {
    private var previewView: PreviewView? = null
    private var mPreview: Preview? = null
    private var mCamera: Camera? = null
    private var mImageCapture: ImageCapture? = null
    private var mCameraProvider: ProcessCameraProvider? = null
    private var isBack = true
    private var preview_result: ImageView? = null

    //	重拍
    private var btn_recapture: ImageView? = null

    // 多张预览
    private var rv_imagelist: RecyclerView? = null

    //确定
    private var btn_ok: ImageView? = null

    //	拍照
    private var btn_capture: ImageView? = null

    //	取消
    private var btn_cancel: TextView? = null

    //切换摄像头
    private var btn_change: ImageView? = null

    //开灯
    private var btn_night: ImageButton? = null
    private var filepath: String? = null
    private var isSaveToAlbum = 0
    private var limit = 0

    //拍照多少张
    private var photo_count = 1
    var previewImageAdapter: PreviewImageAdapter? = null;
    private var TAG = "CameraXActivity"


    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_camerax_photo)
        previewView = findViewById(R.id.previewView)
        preview_result = findViewById(R.id.preview_result)
        btn_capture = findViewById(R.id.btn_capture)
        btn_recapture = findViewById(R.id.btn_recapture)
        btn_ok = findViewById(R.id.btn_ok)
        btn_cancel = findViewById(R.id.btn_cancel)
        btn_change = findViewById(R.id.btn_change)
        btn_night = findViewById(R.id.btn_night)
        btn_capture?.setOnClickListener(this)
        btn_recapture?.setOnClickListener(this)
        btn_ok?.setOnClickListener(this)
        btn_cancel?.setOnClickListener(this)
        btn_change?.setOnClickListener(this)
        btn_night?.setOnClickListener(this)
        btn_ok!!.visibility = View.GONE
        btn_recapture!!.visibility = View.GONE
        isSaveToAlbum = intent.getIntExtra(CameraConstans.FACEPHOTO_isSaveToAlbum, 0)
        photo_count = intent.getIntExtra(CameraConstans.FACEPHOTO_count, 1)
        val isFront = intent.getIntExtra(CameraConstans.FACEPHOTO_isFront, 0)
        isBack = isFront != 1
        limit = intent.getIntExtra(CameraConstans.FACEPHOTO_limit, 1024)
        ensureCameraPermission()
        previewView?.setOnTouchListener(OnTouchListener { v, event ->
            try {
                val action = FocusMeteringAction.Builder(
                        previewView!!.getMeteringPointFactory()
                                .createPoint(event.x, event.y)).build()
                showTapView(event.x.toInt(), event.y.toInt(), previewView!!)
                Log.d("Camera", "Focus camera")
                mCamera!!.cameraControl.startFocusAndMetering(action)
            } catch (e: Exception) {
                Log.e("Camera", "Error focus camera")
            }
            false
        })
        if (photo_count > 1) {
            rv_imagelist = findViewById(R.id.rv_imagelist)
            var linearLayoutManager = LinearLayoutManager(this)
            linearLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
            rv_imagelist?.layoutManager = linearLayoutManager
            previewImageAdapter = PreviewImageAdapter(this@CameraXActivity);
            rv_imagelist?.adapter = previewImageAdapter
        }
    }


    override fun onClick(v: View) {
        if (v === btn_capture) {
            //	拍照
            ensureAudioStoragePermission(REQUEST_STORAGE)
        } else if (v === btn_recapture) {
            //	重拍
            filepath = null
            setButtomControlStatus(CAPTURED_IDEL)
            deleteCacheFile()
        } else if (v === btn_ok) {
            //确定
            val list = ArrayList<CameraImageBean>()
            if (photo_count > 1) {
                previewImageAdapter?.let {
                    list.addAll(it.data)
                }
            } else {
                list.add(CameraImageBean(filepath))
            }
            setResult(
                    Activity.RESULT_OK,
                    Intent().putExtra(CameraConstans.CALL_BACK_PHOTOLIST_CODE, list) )
            finish()
            saveAlbum()
        } else if (v === btn_cancel) {
            //	取消
            finish()
            deleteCacheFile()
        } else if (v === btn_change) {
            //切换摄像头
            if (mCameraProvider != null) {
                isBack = !isBack
                bindPreview(mCameraProvider!!, previewView!!)
                if (!isBack) {
                    btn_night?.visibility = View.GONE
                } else {
                    btn_night?.visibility = View.VISIBLE
                }
            }
        } else if (v === btn_night) {
            //开灯
            onChangeNight()
        }
    }

    private fun saveAlbum() {
        if (isSaveToAlbum == 1) {
            if (photo_count > 1) {
                previewImageAdapter?.let {
                    CameraFileUtils.copyFileList2Album(application, it.data, CameraConstans.IMAGEPATH)
                }
            } else {
                CameraFileUtils.copyFile2Album(application, filepath, CameraConstans.IMAGEPATH)
            }
        }
    }

    /**
     * 删除目前保存的文件
     */
    private fun deleteCacheFile() {
        if (photo_count > 1) {
            previewImageAdapter?.let {
                CameraFileUtils.deleteCacheFileList(application, it.data)
            }
        } else {
            CameraFileUtils.deleteCacheFile(application, filepath)
        }
    }

    override fun countChange(count: Int) {
        try {
            if (count > 0) {
                btn_ok!!.visibility = View.VISIBLE
                rv_imagelist?.smoothScrollToPosition(count - 1)
            } else {
                btn_ok!!.visibility = View.GONE
            }
            if (count >= photo_count) {
                btn_capture!!.visibility = View.GONE
            } else {
                btn_capture!!.visibility = View.VISIBLE
            }
        } catch (e: Exception) {
        }

    }

    private fun setButtomControlStatus(isCapture: Int) {
        if (photo_count == 1) {
            if (CAPTURED_IDEL == isCapture) {
                //正在拍照
                btn_cancel!!.visibility = View.VISIBLE
                btn_capture!!.visibility = View.VISIBLE
                btn_ok!!.visibility = View.GONE
                btn_recapture!!.visibility = View.GONE
                preview_result!!.visibility = View.GONE
                if (!isBack) {
                    btn_night?.visibility = View.GONE
                } else {
                    btn_night?.visibility = View.VISIBLE
                }
                btn_change?.visibility = View.VISIBLE
                previewView?.visibility = View.VISIBLE
            } else if (CAPTURED_SURE == isCapture) {
                //拍照成功
                btn_cancel!!.visibility = View.GONE
                btn_capture!!.visibility = View.GONE
                btn_ok!!.visibility = View.VISIBLE
                btn_recapture!!.visibility = View.VISIBLE
                btn_night?.visibility = View.GONE
                btn_change?.visibility = View.GONE
                previewView?.visibility = View.GONE
            } else if (CAPTURED_SAVEING == isCapture) {
                //拍照等待 裁剪回调
                btn_cancel!!.visibility = View.GONE
                btn_capture!!.visibility = View.GONE
                btn_ok!!.visibility = View.GONE
                btn_recapture!!.visibility = View.GONE
                btn_night?.visibility = View.GONE
                btn_change?.visibility = View.GONE
            }
        } else {
            preview_result!!.visibility = View.GONE
            btn_recapture!!.visibility = View.GONE

            if (CAPTURED_IDEL == isCapture || CAPTURED_SURE == isCapture) {
                //正在拍照
                btn_cancel!!.visibility = View.VISIBLE
                btn_capture!!.visibility = View.VISIBLE
                if (!isBack) {
                    btn_night?.visibility = View.GONE
                } else {
                    btn_night?.visibility = View.VISIBLE
                }
                btn_change?.visibility = View.VISIBLE
                previewView?.visibility = View.VISIBLE
            } else if (CAPTURED_SAVEING == isCapture) {
                //拍照等待 裁剪回调
                btn_cancel!!.visibility = View.VISIBLE
                btn_capture!!.visibility = View.GONE
                if (!isBack) {
                    btn_night?.visibility = View.GONE
                } else {
                    btn_night?.visibility = View.VISIBLE
                }
                btn_change?.visibility = View.VISIBLE
            }
        }
    }

    //灯光
    fun onChangeNight() {
        val flashMode = mImageCapture!!.flashMode
        if (flashMode == ImageCapture.FLASH_MODE_ON) {
            mImageCapture!!.flashMode = ImageCapture.FLASH_MODE_AUTO
            btn_night!!.setImageResource(R.drawable.camerax_flash_auto)
        } else if (flashMode == ImageCapture.FLASH_MODE_OFF) {
            mImageCapture!!.flashMode = ImageCapture.FLASH_MODE_ON
            btn_night!!.setImageResource(R.drawable.camerax_flash_on)
        } else if (flashMode == ImageCapture.FLASH_MODE_AUTO) {
            mImageCapture!!.flashMode = ImageCapture.FLASH_MODE_OFF
            btn_night!!.setImageResource(R.drawable.camerax_flash_off)
        }
    }

    private fun bindPreview(
            cameraProvider: ProcessCameraProvider,
            previewView: PreviewView) {
        val cameraSelector =
                if (isBack) CameraSelector.DEFAULT_BACK_CAMERA else CameraSelector.DEFAULT_FRONT_CAMERA
        val metrics = DisplayMetrics().also {
            previewView.display.getRealMetrics(it)
        }
        val ration = 1f
        val applyWidthPixels = (metrics.widthPixels * ration).toInt()
        val applyHeightPixel = (metrics.heightPixels * ration).toInt()
        val resolution = Size(applyWidthPixels, applyHeightPixel)
        val rotation = (getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay.rotation
        // Preview用例配置，这里经过了大量的测试得到的最兼容的配置
        val previewBuilder = Preview.Builder()
                .setMaxResolution(resolution)
//            .setTargetAspectRatio(screenAspectRatio)
                .setTargetResolution(resolution)
                .setTargetRotation(rotation);

        val imageCaptureBuilder = ImageCapture.Builder()
                .setMaxResolution(resolution)
                // 尽量用screen AspectRation，fix SM-J600G 预览拉伸
                // .setTargetAspectRatio(applyWidthPixels / applyHeightPixel)
                //设置默认比例，目前有RATIO_4_3和RATIO_16_9两种
                .setTargetAspectRatio(AspectRatio.RATIO_16_9)
                .setTargetRotation(rotation)
//                .setTargetRotation(previewView.display.rotation)
//                .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY);

        setPreviewExtender(previewBuilder, cameraSelector)
        setCaptureExtender(imageCaptureBuilder, cameraSelector)

        mPreview = previewBuilder.build()
        mImageCapture = imageCaptureBuilder.build()

        // 配置此处的原因是 预览界面与相机捕获界面一致
        mImageCapture?.setCropAspectRatio(Rational(applyWidthPixels, applyHeightPixel))
        //  mImageCapture.setViewPortCropRect(new Rect(100,100,500,1000));

        cameraProvider.unbindAll()

        mCamera = cameraProvider.bindToLifecycle(
                this, cameraSelector,
                mPreview, mImageCapture)
        mPreview!!.setSurfaceProvider(previewView.surfaceProvider)
        Log.d("Camera", "bindPreview " + Thread.currentThread().id)
    }

    /**
     * 权限
     *
     * @param requestId
     */
    private fun ensureAudioStoragePermission(requestId: Int) {
        if (requestId == REQUEST_STORAGE) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(
                        this,
                        arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                        requestId
                )
                return
            }
            //拍照
            takenPictureInternal()
        }
    }

    @SuppressLint("RestrictedApi")
    private fun takenPictureInternal() {
        var start = System.currentTimeMillis();
        if (mImageCapture != null) {
            filepath = CameraFileUtils.getImageSaveRootPath(this.application) + System.currentTimeMillis() + ".jpeg";
            setButtomControlStatus(CAPTURED_SAVEING)
            val outputFileOptions: ImageCapture.OutputFileOptions = ImageCapture.OutputFileOptions.Builder(File(filepath))
                    // .Builder( getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
                    .build()
            mImageCapture!!.takePicture(outputFileOptions, CameraXExecutors.mainThreadExecutor(),
                    object : ImageCapture.OnImageSavedCallback {
                        override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                            Log.d(TAG, "  用时：takenPictureInternal  " + (System.currentTimeMillis() - start))
                            Thread(Runnable {
                                var bitmap: Bitmap
                                try {
                                    bitmap = BitmapFactory.decodeFile(filepath)
                                    bitmap = rotateBitmap(isBack, bitmap)
                                    CameraFileUtils.savePictureByBitmap(filepath, bitmap)
                                    var file = File(filepath)
                                    Log.d(TAG, "文件压缩前：" + " 大小：" + file.length() + "   " + CameraFileUtils.getReadableFileSize(file.length()) + " 路径：" + file.getAbsolutePath())
                                    if (file.length() > limit * 1024) {
                                        val startZipTime = System.currentTimeMillis()
                                        val file1 = Luban.with(application)[file.getAbsolutePath()]
                                        val endZipTime = System.currentTimeMillis()
                                        Log.d(TAG, "文件压缩后：" + " 大小：" + CameraFileUtils.getReadableFileSize(file1.length()) + " 用时：" + (endZipTime - startZipTime) + " 路径：" + file1.absolutePath)
                                        filepath = file1.absolutePath
                                    }
                                    runOnUiThread(Runnable {
                                        if (photo_count > 1) {
                                            setButtomControlStatus(CAPTURED_SURE)
                                            previewImageAdapter?.addItem(CameraImageBean(filepath))
                                        } else {
                                            preview_result?.setImageBitmap(bitmap)
                                            preview_result?.setVisibility(View.VISIBLE)
                                            setButtomControlStatus(CAPTURED_SURE)
                                        }
                                    })

                                } catch (e: Exception) {
                                } finally {
                                    Log.d(TAG, "  用时：" + (System.currentTimeMillis() - start))

                                }
                            }).start()
                        }

                        override fun onError(exception: ImageCaptureException) {
                            Log.d("Camera", "onError:" + exception.imageCaptureError)
                        }
                    })
        }
    }


    private fun ensureCameraPermission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    this,
                    arrayOf(Manifest.permission.CAMERA),
                    REQUEST_CAMERA
            )
            return
        }
        setupCamera(previewView)
    }

    private fun setupCamera(previewView: PreviewView?) {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener(Runnable {
            try {
                mCameraProvider = cameraProviderFuture.get()
                bindPreview(mCameraProvider!!, previewView!!)
            } catch (e: ExecutionException) {
                e.printStackTrace()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
        }, ContextCompat.getMainExecutor(this))
    }

    override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<String>,
            grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        for (result in grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return
            }
        }
        when (requestCode) {
            REQUEST_CAMERA -> setupCamera(previewView)
            REQUEST_STORAGE -> takenPictureInternal()
            else -> {
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mCameraProvider?.shutdown()
    }


}